#include "comm/my_str.h"
#include "comm/my_log.h"

void test_str()
{
    my_str_t str = MY_STRING("aaaa");
    if (str.len != sizeof("aaaa") - 1 ||
        strncmp(str.data, "aaaa", (size_t)str.len) != 0) {
        MY_LOG_FATAL("unexcept result");
    }

    my_str_t str1 = MY_NULL_STRING;
    if (str1.len != 0 || str1.data != NULL) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "bbbb");
    if (str.len != sizeof("bbbb") - 1 ||
        strncmp(str.data, "bbbb", (size_t)str.len) != 0) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET_NULL(&str);
    if (str.len != 0 || str.data != NULL) {
        MY_LOG_FATAL("unexcept result");
    }

    char str_a[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaa";
    char str_b[64];
    char *p = my_copy(str_b, str_a, sizeof(str_a));
    if (p != str_b || strncmp(str_b, str_a, sizeof(str_a))) {
        MY_LOG_FATAL("unexcept result");
    }

    char buf[64];
    MY_STR_SET(&str, "abcdefghijklmnopqrst");
    my_str_to_string(&str, buf, sizeof(buf));
    if (strlen(buf) != (size_t)str.len || 
        strncmp(buf, str.data, (size_t)str.len) != 0) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "aaaa");
    MY_STR_SET(&str1, "aaaa");
    if (my_str_cmp(&str, &str1) != 0) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "aaaa");
    MY_STR_SET(&str1, "AAAA");
    if (my_str_cmp(&str, &str1) != 1) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "AAAA");
    MY_STR_SET(&str1, "aaaa");
    if (my_str_cmp(&str, &str1) != -1) {
        MY_LOG_FATAL("unexcept result");
    }

    if (my_str_case_cmp(&str, &str1) != 0) {
        MY_LOG_FATAL("unexcept result");
    }

    int64_t res;

    MY_STR_SET(&str, "+123");
    if (!my_str_to_int64(&str, &res) || res != 123) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "-123");
    if (!my_str_to_int64(&str, &res) || res != -123) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "123");
    if (!my_str_to_int64(&str, &res) || res != 123) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "123.");
    if (my_str_to_int64(&str, &res)) {
        MY_LOG_FATAL("unexcept result");
    }
}

void test_sprintf()
{
    char buf[1024];
    int n;

    n = my_snprintf(buf, sizeof(buf), "%d", 100);
    buf[n] = '\0';
    printf("%s\n", buf);

    n = my_snprintf(buf, sizeof(buf), "%ld", 100);
    buf[n] = '\0';
    printf("%s\n", buf);

    n = my_snprintf(buf, sizeof(buf), "%d", (int64_t)-1);
    buf[n] = '\0';
    printf("%s\n", buf);

    n = my_snprintf(buf, sizeof(buf), "%ud", (int64_t)-1);
    buf[n] = '\0';
    printf("%s\n", buf);

    n = my_snprintf(buf, sizeof(buf), "%xd", 100);
    buf[n] = '\0';
    printf("%s\n", buf);

    n = my_snprintf(buf, sizeof(buf), "%Xd", 100);
    buf[n] = '\0';
    printf("%s\n", buf);

    my_snprintf(buf, sizeof(buf), "");
    buf[n] = '\0';
    printf("%s\n", buf);

    my_str_t str = MY_STRING("zxy");
    n = my_snprintf(buf, sizeof(buf), "%d %f %2.3f %p %c %s %v", 100, 1.1, 2.2, (void *)0, 'a', "abc", &str);
    buf[n] = '\0';
    printf("%s\n", buf);
}

void test_my_str_to_double()
{
    double res;

    my_str_t str;

    MY_STR_SET(&str, "+123");
    if (!my_str_to_double(&str, &res) || res > 123 || res < 123) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "-123");
    if (!my_str_to_double(&str, &res) || res > -123 || res < -123) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "123");
    if (!my_str_to_double(&str, &res) || res > 123 || res < 123) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "+123.123");
    if (!my_str_to_double(&str, &res) || res > 123.123 || res < 123.123) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "-123.123");
    if (!my_str_to_double(&str, &res) || res > -123.123 || res < -123.123) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "123.123");
    if (!my_str_to_double(&str, &res) || res > 123.123 || res < 123.123) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "+123.123e+12");
    if (!my_str_to_double(&str, &res) || res > 123.123 * pow10(12) || res < 123.123 * pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "-123.123e+12");
    if (!my_str_to_double(&str, &res) || res > -123.123 * pow10(12) || res < -123.123 * pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "123.123e+12");
    if (!my_str_to_double(&str, &res) || res > 123.123 * pow10(12) || res < 123.123 * pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "+123.123e12");
    if (!my_str_to_double(&str, &res) || res > 123.123 * pow10(12) || res < 123.123 * pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "-123.123e12");
    if (!my_str_to_double(&str, &res) || res > -123.123 * pow10(12) || res < -123.123 * pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "123.123e12");
    if (!my_str_to_double(&str, &res) || res > 123.123 * pow10(12) || res < 123.123 * pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "+123.123e-12");
    if (!my_str_to_double(&str, &res) || res > 123.123 / pow10(12) || res < 123.123 / pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "-123.123e-12");
    if (!my_str_to_double(&str, &res) || res > -123.123 / pow10(12) || res < -123.123 / pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "123.123e-12");
    if (!my_str_to_double(&str, &res) || res > 123.123 / pow10(12) || res < 123.123 / pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "+123e12");
    if (!my_str_to_double(&str, &res) || res > 123 * pow10(12) || res < 123 * pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "-123e+12");
    if (!my_str_to_double(&str, &res) || res > -123 * pow10(12) || res < -123 * pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }

    MY_STR_SET(&str, "123e-12");
    if (!my_str_to_double(&str, &res) || res > 123 / pow10(12) || res < 123 / pow10(12)) {
        MY_LOG_FATAL("unexcept result");
    }
}

void test_parse_size()
{
    int64_t res;

    if (!my_parse_size("1024", &res) || res != 1024) {
        MY_LOG_FATAL("except 1024, but got other");
    }

    if (!my_parse_size("1K", &res) || res != 1024) {
        MY_LOG_FATAL("except 1024, but got other");
    }

    if (!my_parse_size("1k", &res) || res != 1024) {
        MY_LOG_FATAL("except 1024, but got other");
    }

    if (!my_parse_size("1M", &res) || res != 1024 * 1024) {
        MY_LOG_FATAL("except 1024 * 1024, but got other");
    }

    if (!my_parse_size("1m", &res) || res != 1024 * 1024) {
        MY_LOG_FATAL("except 1024 * 1024, but got other");
    }

    if (!my_parse_size("1G", &res) || res != 1024 * 1024 * 1024) {
        MY_LOG_FATAL("except 1024 * 1024 * 1024, but got other");
    }

    if (!my_parse_size("1g", &res) || res != 1024 * 1024 * 1024) {
        MY_LOG_FATAL("except 1024 * 1024 * 1024, but got other");
    }

    if (!my_parse_size("1T", &res) || res != (int64_t)1024 * 1024 * 1024 * 1024) {
        MY_LOG_FATAL("except 1024 * 1024 * 1024, but got other");
    }

    if (!my_parse_size("1t", &res) || res != (int64_t)1024 * 1024 * 1024 * 1024) {
        MY_LOG_FATAL("except 1024 * 1024 * 1024, but got other");
    }

    if (my_parse_size("1x", &res)) {
        MY_LOG_FATAL("except false but got true");
    }

    if (my_parse_size("1xx", &res)) {
        MY_LOG_FATAL("except false but got true");
    }
}

int main()
{
    test_str();
    test_sprintf();
    test_my_str_to_double();
    test_parse_size();

    MY_LOG_DEBUG("test pass");
}